from common.global_var import *
from common import Task

class TaskManager(object):
    """
    任务管理类，提供对任务的各种操作
    + 添加任务
    + 删除任务
    + 查询任务
    """
    def __init__(self):
        
        self.__tasks = {}
    
    @property
    def tasks(self) -> list:
        '''
        获取场景中已经接收到的任务
        '''
        return list(self.__tasks.values())

    @property
    def tasks_info(self) -> list:
        '''
        获取场景中已经接收到的任务
        '''
        return list(map(lambda task: task.info, self.__tasks.values()))

    @property
    def tasks_waiting(self) -> list:
        '''
        获取任务列表中还未执行的任务
        '''
        result = []
        for _id, _task in self.__tasks.items():
            if _task.status == Status_Task.Waiting:
                result.append(_task)
        return result

    def add_tasks(self, tasks, now_time) -> list:
        '''
        一次性添加一个或多个任务，返回一个数组，包含所有添加成功的任务id
        '''
        if not type(tasks) is list:
            tasks = [tasks]

        ids = []

        for task in tasks:
            if self.__task_is_valid(task, now_time):
                ids.append(self.__append_task(task))

        return ids

    def __task_is_valid(self, task: dict, now) -> bool:
        '''
        具有以下特征的任务称为合理任务，可以添加
        - 任务中各个参数之间要符合逻辑关系
          - start_time < end_time
          - containers 是正整数
        - end_time 不能早于当前时间
        - start_pos 和 end_pos 序号要合理，[1, 74]
        - end_pos 可以是空的，但是不可以跟 start_pos 一样
        '''
        start_time = task.get('start_time')
        end_time = task.get('end_time')
        start_pos = task.get('start_pos')
        end_pos = task.get('end_pos', None)
        containers = task.get('containers')

        # 除了 end_pos 之外缺少任意一个属性都不行
        if not (start_time and start_pos and containers):
            print((start_time, start_pos, containers))
            print('缺少属性')
            return False

        # 开始时间晚于结束时间，不合逻辑
        # if not start_time < end_time:
        #     print('开始时间晚于结束时间，不合逻辑')
        #     return False

        # 卸货点与装货点重合
        if end_pos == start_pos:
            print('卸货点与装货点重合')
            return False

        # 现在已经结束了的任务
        if start_time < now:
            print('现在已经结束了的任务')
            return False

        # 起始位置合法
        if not start_pos in range(1, 75):
            print('起始位置不合法')
            return False

        # 终止位置合法
        if end_pos and (not end_pos in range(1, 75)):
            print('终止位置不合法')
            return False

        # 集装箱的数量是正整数
        if not (isinstance(containers, int) and containers > 0):
            print('集装箱的数量不是正整数')
            return False

        return True

    def __append_task(self, task: dict) -> str:
        '''
        将 task 添加到环境中
        '''
        task_id = self.unique_id(task)
        task['id'] = task_id
        self.__tasks[task_id] = Task(task)
        return task_id
        
    def unique_id(self, task) -> str:
        '''
        为每个任务生成独一无二的id
        '''
        _id = str(hash(str(task)))[-6:]
        while _id in self.__tasks.keys():
            _id = str(hash(_id + 'id'))[-6:]
        return _id
